#ifndef EVENTS_HPP
#define EVENTS_HPP

#include "config.h"

#include <string>
#include <functional>
#include <vector>

#include <dexode/eventbus/internal/event_id.hpp>

namespace AppEvent
{
    // Tag 数据表发生变动
    struct TagEvent
    {
        enum Type
        {
            Add,
            Delete,
            Updated,
        };

        Type type;
    };

    // 某个WorkItem发生变动
    struct ItemEvent {};

    // RedMineIssue 数据发生变动
    struct IssueEvent {};

    // RedMineActivity 数据发生变动
    struct ActivityEvent {};

    // 应用程序配置变动
    struct AppConfigEvent {};

    // 字体大小发生更改
    struct FontEvent {};

    // 应用程序样式改变
    struct StyleEvent {};

    // 模板信息发生更改
    struct TemplateChangedEvent {};

    // 任务信息更改
    struct TaskInfoChanged {};

    struct DialogMessage
    {
        enum Type {
            eDebug,
            eInfo,
            eWarning,
            eError,

            eProgressDialog,
        };

        Type type{eDebug};
        std::string msg{};
        bool        show{};
    };

    struct StatusMessage
    {
        static constexpr int MAX_OPERATION_CNT = 3;
        using notify_cb = std::function<void()>;

        struct notify_op
        {
            std::string name{};
            notify_cb   cb;
        };

        std::string msg{};
        double timeout{};

        int op_cnt{};
        notify_op operations[MAX_OPERATION_CNT];
    };

    struct AppUpgradeEvent
    {
        enum Flags
        {
            eAlreadyLatest = 0x00,
            eHasNewVersion = 0x01,
            eIsRecommended = 0x02,
        };

        int         update_flags{};
        std::string current_version{};
        std::string latest_version{};
        std::string release_note{};
    };

    struct CreateDiaryItemEvent {
        std::string date{};
        std::string title{};
        std::string note{};
        int issue_id{};
        int act_id{};
        double time{};
        std::vector<int> tags{};
    };

    struct SelectTabEvent{
        enum TabId {
            eDiary = 0,
            eRedMine,
            eStatistics,
            eTaskSchedule,
            eSurveyor,

            eTabIdCount
        };
        TabId which;

        static DIARY_APP_SDK_API SelectTabEvent fromTabName(const std::string &name);
        static DIARY_APP_SDK_API const char *tabName(TabId id);
    };

    struct FillByMainlineTaskEvent {
        double      total_hour; // 多少小时
        std::string date;       // 日期
    };

    struct QuickShowStatisticsEvent {
        std::string date_prefix;
    };

    struct ShowStatisticsByRangeEvent {
        std::string start, end;
    };

    struct CopyTextEvent {
        std::string text;
    };

    // 调查/回应
    struct SurveyEvent {
        std::string date_start;
        std::string date_end;
    };

    struct RespondEvent {
        std::string content;
    };
}

#if _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4910)
#endif

#define SHARED_EVENT(T) \
extern template struct DIARY_APP_SDK_API dexode::eventbus::internal::type_id_ptr<T>

// 记得同步修改 events.cpp

SHARED_EVENT(AppEvent::TagEvent);
SHARED_EVENT(AppEvent::ItemEvent);
SHARED_EVENT(AppEvent::IssueEvent);
SHARED_EVENT(AppEvent::ActivityEvent);
SHARED_EVENT(AppEvent::AppConfigEvent);
SHARED_EVENT(AppEvent::FontEvent);
SHARED_EVENT(AppEvent::StyleEvent);
SHARED_EVENT(AppEvent::TemplateChangedEvent);
SHARED_EVENT(AppEvent::TaskInfoChanged);
SHARED_EVENT(AppEvent::DialogMessage);
SHARED_EVENT(AppEvent::StatusMessage);
SHARED_EVENT(AppEvent::AppUpgradeEvent);
SHARED_EVENT(AppEvent::CreateDiaryItemEvent);
SHARED_EVENT(AppEvent::SelectTabEvent);
SHARED_EVENT(AppEvent::FillByMainlineTaskEvent);
SHARED_EVENT(AppEvent::QuickShowStatisticsEvent);
SHARED_EVENT(AppEvent::ShowStatisticsByRangeEvent);
SHARED_EVENT(AppEvent::CopyTextEvent);
SHARED_EVENT(AppEvent::SurveyEvent);
SHARED_EVENT(AppEvent::RespondEvent);

#undef SHARED_EVENT

#if _MSC_VER
#pragma warning(pop)
#endif

#endif // EVENTS_HPP
